/*!
\copyright  Copyright (c) 2022 Qualcomm Technologies International, Ltd.
            All Rights Reserved.
            Qualcomm Technologies International, Ltd. Confidential and Proprietary.
\version    
\file       google_finder_private.h
\brief      Header file for Google Finder private data.
*/

#ifndef GOOGLE_FINDER_PRIVATE_H_
#define GOOGLE_FINDER_PRIVATE_H_

#ifdef INCLUDE_GOOGLE_FINDER
#include "bt_types.h"
#include "domain_message.h"

/* One time random nonce length */
#define GOOGLE_FINDER_ONE_TIME_NONCE_LEN           (8)

/* Google Finder Supported Version */
#define GOOGLE_FINDER_SUPPORTED_VERSION            (1)
#define GOOGLE_FINDER_VERSION_NO_LEN               (1)

/* Google Finder Read Response Format */
#define GOOGLE_FINDER_READ_RSP_VERSION_OFFSET      (0)
#define GOOGLE_FINDER_READ_RSP_NONCE_OFFSET        (GOOGLE_FINDER_READ_RSP_VERSION_OFFSET + sizeof(uint8))

/* Beacon Action Read Response Length */
#define GOOGLE_FINDER_READ_RSP_LEN                 (GOOGLE_FINDER_ONE_TIME_NONCE_LEN + GOOGLE_FINDER_VERSION_NO_LEN)

/* Invalid connection id */
#define GOOGLE_FINDER_INVALID_CID                  (0x0)

/* One Time Authentication Key Length */
#define GOOGLE_FINDER_ONE_TIME_AUTH_KEY_LEN        (8)

/* Beacon Write Request mininum length */
#define GOOGLE_FINDER_BEACON_WRITE_REQ_MIN_LEN     (10)

/* Beacon Action Write Request Data Offset and length */
#define GOOGLE_FINDER_BEACON_REQ_DATA_ID_OFFSET    (0)
#define GOOGLE_FINDER_BEACON_REQ_DATA_LEN_OFFSET   (GOOGLE_FINDER_BEACON_REQ_DATA_ID_OFFSET + sizeof(uint8))
#define GOOGLE_FINDER_BEACON_REQ_OTA_KEY_OFFSET    (GOOGLE_FINDER_BEACON_REQ_DATA_LEN_OFFSET + sizeof(uint8))
#define GOOGLE_FINDER_BEACON_REQ_ADD_DATA_OFFSET   (GOOGLE_FINDER_BEACON_REQ_OTA_KEY_OFFSET + GOOGLE_FINDER_ONE_TIME_AUTH_KEY_LEN)

#define GOOGLE_FINDER_BEACON_REQ_DATA_ID_LEN       (1)
#define GOOGLE_FINDER_BEACON_REQ_DATA_SIZE_LEN     (1)

/* One time authentication field in beacon action PDUs */
#define GOOGLE_FINDER_OTA_MAJ_VERSION_OFFSET     (0)
#define GOOGLE_FINDER_OTA_NONCE_OFFSET (GOOGLE_FINDER_OTA_MAJ_VERSION_OFFSET + sizeof(uint8))
#define GOOGLE_FINDER_OTA_DATA_ID_OFFSET (GOOGLE_FINDER_OTA_NONCE_OFFSET + GOOGLE_FINDER_ONE_TIME_NONCE_LEN)
#define GOOGLE_FINDER_OTA_DATA_LENGTH_OFFSET (GOOGLE_FINDER_OTA_DATA_ID_OFFSET + sizeof(uint8))
#define GOOGLE_FINDER_OTA_ADD_DATA_OFFSET (GOOGLE_FINDER_OTA_DATA_LENGTH_OFFSET + sizeof(uint8))
#define GOOGLE_FINDER_BEACON_OTA_FIXED_DATA_LEN    (GOOGLE_FINDER_VERSION_NO_LEN + \
                                                    GOOGLE_FINDER_ONE_TIME_NONCE_LEN + \
                                                    GOOGLE_FINDER_BEACON_REQ_DATA_ID_LEN + \
                                                    GOOGLE_FINDER_BEACON_REQ_DATA_SIZE_LEN)

/* Authentication segment length in Beacon Action Service Response */
#define GOOGLE_FINDER_BEACON_RSP_AUTH_LEN          (8)
#define GOOGLE_FINDER_BEACON_RSP_DATA_ID_LEN       (1)
#define GOOGLE_FINDER_BEACON_RSP_DATA_LEN          (1)

/* Beacon Action Service Response Data Offset */
#define GOOGLE_FINDER_BEACON_RSP_DATA_ID_OFFSET    (0)
#define GOOGLE_FINDER_BEACON_RSP_DATA_LEN_OFFSET   (GOOGLE_FINDER_BEACON_RSP_DATA_ID_OFFSET + sizeof(uint8))
#define GOOGLE_FINDER_BEACON_RSP_AUTH_OFFSET       (GOOGLE_FINDER_BEACON_RSP_DATA_LEN_OFFSET + sizeof(uint8))
#define GOOGLE_FINDER_BEACON_RSP_ADD_DATA_OFFSET   (GOOGLE_FINDER_BEACON_RSP_AUTH_OFFSET + GOOGLE_FINDER_BEACON_RSP_AUTH_LEN)

/* Beacon Action Service Response padding data value */
#define GOOGLE_FINDER_BEACON_RSP_PADDING           (0x01)

/* Google Finder Keys Types */
#define GOOGLE_FINDER_KEY_TYPE_LEN                 (1)
#define finder_key_type_t                          uint8

#define GOOGLE_FINDER_RECOVERY_KEY                 (0x01)
#define GOOGLE_FINDER_RING_KEY                     (0x02)
#define GOOGLE_FINDER_UNWANTED_TRACKING_KEY        (0x03)

/* Google Finder Keys Length */
#define GOOGLE_FINDER_EIK_LEN                      (32)
#define GOOGLE_FINDER_ACCOUNT_KEY_LEN              (16)
#define GOOGLE_FINDER_SECONDARY_KEY_LEN            (8)
#define GOOGLE_FINDER_RING_KEY_LEN                 (8)
#define GOOGLE_FINDER_RECOVERY_KEY_LEN             (8)
#define GOOGLE_FINDER_UNWANTED_TRACKING_KEY_LEN    (8)

/* Beacon Read Parameter data lengths */
#define GOOGLE_FINDER_BEACON_PARAM_RSP_ADD_DATA_LEN  (16)
#define GOOGLE_FINDER_CLOCK_VALUE_LEN                (4)
#define GOOGLE_FINDER_ZERO_PADDING_LEN               (8)

/* Elliptic curve type for encryption */
#define GOOGLE_FINDER_SECP160R1                    (0x00)
#define GOOGLE_FINDER_SECP256R1                    (0x01)

/* Ring components to indicate number of components to ring */
#define GOOGLE_FINDER_NO_COMPONENT                 (0x00)
#define GOOGLE_FINDER_SINGLE_COMPONENT             (0x01)
#define GOOGLE_FINDER_TWO_COMPONENTS               (0x02)
#define GOOGLE_FINDER_THREE_COMPONENTS             (0x03)

/* Ring Volume Selection */
#define GOOGLE_FINDER_NO_RING_VOL_SELECTION        (0x00)
#define GOOGLE_FINDER_RING_VOL_SELECTION           (0x01)

/* Beacon Read Parameter response data offset */
#define GOOGLE_FINDER_BEACON_PARAM_RSP_TX_POWER_OFFSET              (0)
#define GOOGLE_FINDER_BEACON_PARAM_RSP_CLOCK_VALUE_OFFSET           (GOOGLE_FINDER_BEACON_PARAM_RSP_TX_POWER_OFFSET + sizeof(uint8))
#define GOOGLE_FINDER_BEACON_PARAM_RSP_ENCRYPT_TYPE_OFFSET          (GOOGLE_FINDER_BEACON_PARAM_RSP_CLOCK_VALUE_OFFSET + GOOGLE_FINDER_CLOCK_VALUE_LEN)
#define GOOGLE_FINDER_BEACON_PARAM_RSP_RING_COMPONENTS_OFFSET       (GOOGLE_FINDER_BEACON_PARAM_RSP_ENCRYPT_TYPE_OFFSET + sizeof(uint8))
#define GOOGLE_FINDER_BEACON_PARAM_RSP_RING_CAPABILITY_OFFSET       (GOOGLE_FINDER_BEACON_PARAM_RSP_RING_COMPONENTS_OFFSET + sizeof(uint8))
#define GOOGLE_FINDER_BEACON_PARAM_RSP_ZERO_PADDING_OFFSET          (GOOGLE_FINDER_BEACON_PARAM_RSP_RING_CAPABILITY_OFFSET + sizeof(uint8))

/* Beacon Read Provisioning state length */
#define GOOGLE_FINDER_PROV_STATE_RSP_ADD_DATA_LEN                (1)
#define GOOGLE_FINDER_PROV_STATE_RSP_ADD_DATA_WITH_P160_EID_LEN  (21)

/* Beacon Read Provisioning Response data offset */
#define GOOGLE_FINDER_PROV_STATE_RSP_STATE_OFFSET                (0)
#define GOOGLE_FINDER_PROV_STATE_RSP_EID_OFFSET                  (1)

/* Beacon Read Provisioning state data bitmask */
#define GOOGLE_FINDER_PROV_STATE_RSP_EIK_SET_FLAG    (1 << 0)
#define GOOGLE_FINDER_PROV_STATE_RSP_OWNER_KEY_FLAG  (1 << 1)

/* Grace time to allow provisioning in pairing mode in seconds */
#define GOOGLE_FINDER_PROVISIONING_EXT_TIMEOUT       (90)

/* If Provider is already provisioned, Seeker sends additional hashed current EIK in SET EIK message */
#define GOOGLE_FINDER_HASH_EIK_LEN                        (8)
#define GOOGLE_FINDER_SET_EIK_ADD_DATA_LEN_MIN            (32)
#define GOOGLE_FINDER_SET_EIK_WITH_HASH_ADD_DATA_LEN      (GOOGLE_FINDER_SET_EIK_ADD_DATA_LEN_MIN + GOOGLE_FINDER_HASH_EIK_LEN)

/* Offset of hashed EIK in Set EIK message */
#define GOOGLE_FINDER_HASH_EIK_OFFSET                (32)

/* Clear EIK message additional data length */
#define GOOGLE_FINDER_CLEAR_EIK_ADD_DATA_LEN         (8)

/* Google Finder Ring Operation Additional Data Offset */
#define GOOGLE_FINDER_RING_DATA_RING_COMPONENT_OFFSET    (0)
#define GOOGLE_FINDER_RING_DATA_RING_TIMEOUT_OFFSET      (GOOGLE_FINDER_RING_DATA_RING_COMPONENT_OFFSET + sizeof(uint8))
#define GOOGLE_FINDER_RING_DATA_RING_VOLUME_OFFSET       (GOOGLE_FINDER_RING_DATA_RING_TIMEOUT_OFFSET + sizeof(uint8) + sizeof(uint8))

/* Google Finder Ring Additional Data length - 4 bytes indicating the ringing state, ringing duration and ringing volume */
#define GOOGLE_FINDER_RING_ADD_DATA_LEN                  (4)

/* Google Finder Ring Operation Volume Level Data Value */
#define GOOGLE_FINDER_RING_DEVICE_VOL_DEFAULT            (0x00)
#define GOOGLE_FINDER_RING_DEVICE_VOL_LOW                (0x01)
#define GOOGLE_FINDER_RING_DEVICE_VOL_MEDIUM             (0x02)
#define GOOGLE_FINDER_RING_DEVICE_VOL_HIGH               (0x03)

/* Ring device and read ring state response data length and offset */
#define GOOGLE_FINDER_RING_DEVICE_RSP_ADD_DATA_LEN              (4)
#define GOOGLE_FINDER_RING_DEVICE_RSP_STATE_OFFSET              (0)
#define GOOGLE_FINDER_RING_DEVICE_RSP_RING_COMPONENT_OFFSET     (GOOGLE_FINDER_RING_DEVICE_RSP_STATE_OFFSET + sizeof(uint8))
#define GOOGLE_FINDER_RING_DEVICE_RSP_RING_DURATION_OFFSET      (GOOGLE_FINDER_RING_DEVICE_RSP_RING_COMPONENT_OFFSET + sizeof(uint8))

#define GOOGLE_FINDER_READ_RING_STATE_RSP_ADD_DATA_LEN          (3)
#define GOOGLE_FINDER_READ_RING_STATE_RSP_RING_COMPONENT_OFFSET (0)
#define GOOGLE_FINDER_READ_RING_STATE_RSP_RING_DURATION_OFFSET  (GOOGLE_FINDER_READ_RING_STATE_RSP_RING_COMPONENT_OFFSET + sizeof(uint8))

#define GOOGLE_FINDER_STOP_RING                                 (0x00)
#define GOOGLE_FINDER_RING_DURATION_INVALID                     (0x00)

/* Google Finder Advertisement data length, offset and value */
#define GOOGLE_FINDER_ADV_RAW_EDDYSTONE_FRAME_LEN                (32)
#define GOOGLE_FINDER_ADV_PADDING_FIELD_LEN                      (11)
#define GOOGLE_FINDER_ADV_TIME_COUNTER_FIELD_LEN                 (4)

#define GOOGLE_FINDER_ADV_FIRST_PADDING_OFFSET                   (0)
#define GOOGLE_FINDER_ADV_FIRST_ROTATION_PERIOD_EXPONENT_OFFSET  (GOOGLE_FINDER_ADV_FIRST_PADDING_OFFSET + GOOGLE_FINDER_ADV_PADDING_FIELD_LEN)
#define GOOGLE_FINDER_ADV_FIRST_TIME_COUNTER_OFFSET              (GOOGLE_FINDER_ADV_FIRST_ROTATION_PERIOD_EXPONENT_OFFSET + 1)
#define GOOGLE_FINDER_ADV_SECOND_PADDING_OFFSET                  (GOOGLE_FINDER_ADV_FIRST_TIME_COUNTER_OFFSET + GOOGLE_FINDER_ADV_TIME_COUNTER_FIELD_LEN)
#define GOOGLE_FINDER_ADV_SECOND_ROTATION_PERIOD_EXPONENT_OFFSET (GOOGLE_FINDER_ADV_SECOND_PADDING_OFFSET + GOOGLE_FINDER_ADV_PADDING_FIELD_LEN)
#define GOOGLE_FINDER_ADV_SECOND_TIME_COUNTER_OFFSET             (GOOGLE_FINDER_ADV_SECOND_ROTATION_PERIOD_EXPONENT_OFFSET + 1)

#define GOOGLE_FINDER_ADV_FIRST_PADDING_VALUE                    (0xFF)
#define GOOGLE_FINDER_ADV_SECOND_PADDING_VALUE                   (0x00)
#define GOOGLE_FINDER_ADV_ROTATION_PERIOD_EXPONENT_VALUE         (10)
#define GOOGLE_FINDER_ADV_INVALID_TIME_COUNTER_VALUE             (0)
#define GOOGLE_FINDER_ADV_MASK_TIME_COUNTER_VALUE                (0xFFFFFC00)
/* First 10 bits are cleared in the time counter, MSB bit starts with 11th bit from LSB 100 00000000 i.e. 1024 */
#define GOOGLE_FINDER_ADV_PUBLIC_KEY_TIME_WINDOW                 (1024)
/* Google Finder will avoid generating a new EID if the current time counter is 10 seconds away from MSB update */
#define GOOGLE_FINDER_ADV_TIME_COUNTER_RELIEF_WINDOW             (10)

/* Macros for Google Finder Advertising data (google_finder_adv_packet) */
#define GOOGLE_FINDER_ADV_STANDARD_DATA_LEN                      (2)
#define GOOGLE_FINDER_ADV_SERVICE_DATA_LEN                       (25)
#define GOOGLE_FINDER_ADV_EDDYSTONE_IDENTIFIER                   (0xFEAA)
#define GOOGLE_FINDER_ADV_E2EE_EID_FRAME_TYPE                    (0x40)
#define GOOGLE_FINDER_ADV_EPHEMERAL_IDENTIFIER_LEN               (20)
#define GOOGLE_FINDER_ADV_P160_DATA_PACKET_SIZE                  (29)

#define GOOGLE_FINDER_ADV_EPHEMERAL_IDENTIFIER_OFFSET            (8)
#define GOOGLE_FINDER_ADV_HASHED_FLAGS_OFFSET                    (28)

/* Hashed Flags in Advertising Data */
#define GOOGLE_FINDER_ADV_HASHED_FLAGS_UNWANTED_TRACKING_PROT_MODE (0x01)

#define GOOGLE_FINDER_ADV_HASHED_FLAGS_BATTERY_BIT_MASK          (0x06)
#define GOOGLE_FINDER_ADV_HASHED_FLAGS_BATTERY_UNSUPPORTED       (0x00)
#define GOOGLE_FINDER_ADV_HASHED_FLAGS_NORMAL_BATTERY            (0x02)
#define GOOGLE_FINDER_ADV_HASHED_FLAGS_LOW_BATTERY               (0x04)
#define GOOGLE_FINDER_ADV_HASHED_FLAGS_CRITICAL_BATTERY          (0x06)


/* Data to be advertised when Advert is stopped intentionally */
#define GOOGLE_FINDER_ADV_INVALID_DATA_PACKET_SIZE               (0)

/*
 * Adv interval for Google Finder Adverts should be <= 2000ms (i.e. 0.5 Hz)
 * Adv Interval values are in ms (units of 0.625).
 */
#define GOOGLE_FINDER_ADV_INTERVAL_MIN      (3000)
#define GOOGLE_FINDER_ADV_INTERVAL_MAX      (3200)

/* As per Google Finder Spec, RPA rotation is mandatory every 1024s(17minutes) */
#define GOOGLE_FINDER_ADV_RPA_ROTATION_TIME_MIN  (16)
#define GOOGLE_FINDER_ADV_RPA_ROTATION_TIME_MAX  (18)

/* RPA should be fixed for 24 hrs if unwanted tracking protection mode is enabled */
#define GOOGLE_FINDER_ADV_RPA_ROTATION_TIME_UNWANTED_TRACKING_PROTECTION (1440)

/* Crypto Algos output data length */
#define GOOGLE_FINDER_ADV_AES_ECB_256_OUTPUT_SIZE                 (32)
#define GOOGLE_FINDER_ADV_P160_PRIVATE_KEY_SIZE                   (20)
#define GOOGLE_FINDER_ADV_P160_COMPRESSED_PUBLIC_KEY_SIZE         (20)

#define GOOGLE_FINDER_MAX_BLE_CONNECTIONS 2

#define GOOGLE_FINDER_FP_MSG_CURR_EDDYSTONE_ID_CLOCK_OFFSET       (0)
#define GOOGLE_FINDER_FP_MSG_CURR_EDDYSTONE_ID_EID_OFFSET         (4)

/*! \brief Google Finder connection specific data structure */
typedef struct
{
    /* Connection ID associated with random nonce */
    uint32    conn_id;
    /* One time random nonce to be stored and used for a transaction per connection instance */
    uint8*    random_nonce;
    /* Account key for the BLE connection */
    uint8*    account_key;
    /* This flag is used to identify the instance which has updated the EIK */
    bool      eik_updated;
}google_finder_instance;

/* Google Finder Ring Operation ringing states */
typedef enum
{
    google_finder_ringing_started = 0x00,
    google_finder_ringing_failed_to_start_or_stop = 0x01,
    google_finder_ringing_stopped_timeout = 0x02,
    google_finder_ringing_stopped_button_press = 0x03,
    google_finder_ringing_stopped_gatt_request = 0x4,
    google_finder_ringing_state_invalid = 0xFF
}google_finder_ringing_state;

/* Google Finder Ring Operation data structure */
typedef struct
{
    uint8                       ring_component;
    uint16                      ring_timeout;    /* In Deciseconds, 1 decisecond = 0.1 second */
    google_finder_instance*     instance;
    uint8                       *ring_nonce;     /* Nonce used to initiate ringing operation */
    google_finder_ringing_state ring_state;
}google_finder_ring_device_data;

/* Google Finder Beacon counter data structure */
typedef struct
{
    uint16    drift_ms;         /* beacon counter fractional clock in milli sec*/
    uint32    beacon_time;      /* current beacon time counter in seconds */
    uint32    trigger_clock;    /* vmclock when second counter was triggered */
}google_finder_beacon_time;

/*! \brief Google Finder task structure */
typedef struct
{
    TaskData                         task;
    google_finder_instance           connection_instance[GOOGLE_FINDER_MAX_BLE_CONNECTIONS];
    google_finder_ring_device_data   ring_data;
    google_finder_beacon_time        beacon_time_data;
    bool                             allow_provisioning : 1;
    bool                             is_pairing_mode : 1;
} googleFinderTaskData;

/*! \brief Internal messages used by Google Finder. */
typedef enum
{
    GOOGLE_FINDER_INTERNAL_PROVISIONING_TIMEOUT = INTERNAL_MESSAGE_BASE,
    GOOGLE_FINDER_INTERNAL_BEACON_TIME_UPDATE,
    GOOGLE_FINDER_INTERNAL_MESSAGE_END
} google_finder_internal_msgs_t;

ASSERT_INTERNAL_MESSAGES_NOT_OVERFLOWED(GOOGLE_FINDER_INTERNAL_MESSAGE_END)

typedef enum
{
    /* Operation was successful */
    google_finder_status_success = 0x00,
    /* Returned in response to a write request when authentication fails */
    google_finder_status_auth_error = 0x80,
    /* Returned when any invalid value is provided or the data received has an unexpected number of bytes */
    google_finder_status_invalid_value = 0x81,
    /* Returned in response to a write request with data id 0x04: Read
       Ephemeral Identity Key with user consent when the device is not in pairing mode */
    google_finder_status_no_user_consent = 0x82
}google_finder_gatt_status_t;

typedef enum
{
    GOOGLE_FINDER_READ_BEACON_PARAMS = 0x00,
    GOOGLE_FINDER_READ_PROVISION_STATE = 0x01,
    GOOGLE_FINDER_SET_EIK = 0x02,
    GOOGLE_FINDER_CLEAR_EIK = 0x03,
    GOOGLE_FINDER_READ_EIK_USER_CONSENT = 0x04,
    GOOGLE_FINDER_RING_DEVICE = 0x05,
    GOOGLE_FINDER_READ_RING_STATE = 0x06,
    GOOGLE_FINDER_ACTIVATE_UNWANTED_TRACKING = 0x07,
    GOOGLE_FINDER_DEACTIVATE_UNWANTED_TRACKING = 0x08
}google_finder_message_id_t;

typedef struct
{
    uint8    data_id;          /* Data id from google_finder_message_id_t */
    uint8    data_len;         /* Overall PDU len */
    uint8    *add_data;        /* Valid pointer to additional data, NULL if length is zero */
    uint8    add_data_len;     /* Additional data length in octets */
    bool     is_rsp;           /* Auth data being requested for Req or Rsp */
    uint8    *ota_key;         /* Expected OTA key, valid for Req */
}google_finder_auth_data_input;

#endif /* INCLUDE_GOOGLE_FINDER */
#endif /* GOOGLE_FINDER_PRIVATE_H_ */
